package com.zb.network.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zb.constant.NetworkConstant;
import com.zb.constant.WorkConstant;
import com.zb.excel.converter.WorkConverter;
import com.zb.entity.*;
import com.zb.network.service.ConNetworkService;
import com.zb.order.service.ConWorkSpareService;
import com.zb.result.PageUtil;
import com.zb.service.*;
import com.zb.vo.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @Author WEN
 * @Date 2023/10/19 0019
 **/
@Service
public class ConNetworkServiceImpl implements ConNetworkService {
    @Resource
    private ZjNetworkService networkService;
    @Resource
    private ZjNetworkStrategyService networkStrategyService;
    @Resource
    private ZjNetworkPathService networkPathService;
    @Resource
    private ZjNetworkFieldValService networkFieldValService;
    @Resource
    private ZjNetworkModuleSettlementService networkModuleSettlementService;
    @Resource
    private ZjNetworkServiceAreaService networkServiceAreaService;
    @Resource
    private ZjWorkOrderService workOrderService;
    @Resource
    private ZjWorkUserService workUserService;
    @Resource
    private ZjNetworkTypeService networkTypeService;
    @Resource
    private ZjAccountService accountService;
    @Resource
    private ZjNetworkEmpRelationService networkEmpRelationService;
    @Resource
    private ZjWorkFeeService workFeeService;
    @Resource
    private ZjWorkSpareService workSpareService;
    @Resource
    private ZjWorkModuleService workModuleService;
    @Resource
    private ConWorkSpareService conWorkSpareService;
    @Resource
    private ZjNetworkTeamAuthenFieldValService networkTeamAuthenFieldValService;
    @Resource
    private ZjNetworkAloneAuthenFieldValService networkAloneAuthenFieldValService;


    // 获取服务商列表
    @Override
    public Map<String, Object> getList(Long custAccId, NetworkSelectVo networkSelectVo) {
        PageUtil.setPageLimit(networkSelectVo);
        long count = networkService.getListCount(custAccId, networkSelectVo);
        if (count <= 0) {
            return PageUtil.pageList(networkSelectVo.getPage(), networkSelectVo.getLimit(), count, new ArrayList<>());
        }
        List<NetworkListVo> voList = networkService.getList(custAccId, networkSelectVo);
        List<Long> networkIds = voList.stream().map(NetworkListVo::getId).toList();
        List<QtyVo> totalOrderQtyVos = workOrderService.getTotalOrderByNetworkIds(networkIds);
        List<QtyVo> serviceOrderQtyVos = workOrderService.getServiceOrderByNetworkIds(networkIds);
        List<ZjNetworkServiceArea> serviceAreas = networkServiceAreaService.getByNetworkIds(voList.stream().map(NetworkListVo::getId).toList());
        voList.forEach(t -> {
            t.setTotalOrderQty(totalOrderQtyVos.stream().filter(f -> Objects.equals(f.getId(), t.getId())).map(QtyVo::getQty).findFirst().orElse(0));
            t.setServiceOrderQty(serviceOrderQtyVos.stream().filter(f -> Objects.equals(f.getId(), t.getId())).map(QtyVo::getQty).findFirst().orElse(0));
            t.setServiceAreas(serviceAreas.stream().filter(f -> Objects.equals(f.getNetworkId(), t.getId())).map(area -> {
                NetworkServiceAreaVo vo = new NetworkServiceAreaVo();
                BeanUtil.copyProperties(area, vo);
                return vo;
            }).toList());
        });
        return PageUtil.pageList(networkSelectVo.getPage(), networkSelectVo.getLimit(), count, voList);
    }

    // 根据服务商ID获取服务商详情
    @Override
    public NetworkDetailVo getDetail(Long id) {
        ZjNetwork network = networkService.getById(id);
        Assert.isTrue(null != network, "服务商ID参数["+ id +"]的数据不存在");

        NetworkDetailVo vo = new NetworkDetailVo();
        BeanUtil.copyProperties(network, vo);
        vo.setStatus(network.getDisabled());
        vo.setCreateTime(network.getGmtCreate());
        vo.setUpdateTime(network.getGmtUpdate());
        ZjNetworkType networkType = networkTypeService.getById(network.getNetworkTypeId());
        if (null != networkType) {
            vo.setNetworkType(networkType.getName());
        }
        QueryWrapper<ZjWorkOrder> orderQueryWrapper = new QueryWrapper<>();
        orderQueryWrapper.select("id", "status", "settlement_status", "end_time", "gmt_create");
        orderQueryWrapper.eq("network_id", id);
        List<ZjWorkOrder> orderList = workOrderService.list(orderQueryWrapper);
        int totalOrder = orderList.size();
        int finishorder = (int) orderList.stream().filter(f -> f.getStatus() == WorkConstant.WORK_STATUS_4).count();

        vo.setTotalOrderQty(totalOrder);
        vo.setFinishOrderQty(finishorder);
        vo.setCancelOrderQty((int) orderList.stream().filter(f -> f.getStatus() == WorkConstant.WORK_STATUS_5).count());
        vo.setHandlerOrderQty((int) orderList.stream().filter(f -> f.getStatus() == WorkConstant.WORK_STATUS_3).count());
        vo.setOrderWaitSettlementQty((int) orderList.stream().filter(f -> f.getSettlementStatus() == WorkConstant.WORK_SETTLEMENT_STATUS_1).count());
        /* 先保留--平均时间
        List<Integer> orderFinishHour = workOrderService.getFinishOrderTimeConsumingByNetworkId(id);
        Float totalHour = (float)orderFinishHour.stream().reduce(0, Integer::sum) / orderFinishHour.size();
        vo.setOrderAverageTimeConsuming(totalHour % 24 == 0? "" : ((int)(totalHour / 24) == 0? "" : (int)(totalHour / 24) + "天") +  ((int)(totalHour / 24 / 60) == 0? "" :  (int)(totalHour / 24 / 60)+ "时"));
         */
        return vo;
    }

    // 获取服务商详情之工单明细列表
    @Override
    public Map<String, Object> getNetworkDetailOrderList(Long networkId, PageUtil pageUtil) {
        Assert.isTrue(networkId != 0, "无效的服务商ID参数["+ networkId +"]");
        PageUtil.setPageLimit(pageUtil);
        List<ZjWorkOrder> orderList = workOrderService.getNetworkDetailOrderList(networkId, pageUtil);
        List<Long> workIds = orderList.stream().map(ZjWorkOrder::getId).toList();
        List<Long> empIds = orderList.stream().map(ZjWorkOrder::getEmpId).distinct().toList();

        List<ZjWorkUser> workUsers = workUserService.getByIds(workIds);
        List<ZjAccount> accounts = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(empIds)) {
            accounts.addAll(accountService.getByIds(empIds));
        }
        List<NetworkDetailOrderListVo> voList = orderList.stream().map(order -> {
            NetworkDetailOrderListVo vo = new NetworkDetailOrderListVo();
            BeanUtil.copyProperties(order, vo);
            vo.setWorkNo(order.getCode());
            vo.setCreateTime(order.getGmtCreate());
            vo.setUpdateTime(order.getGmtUpdate());
            ZjWorkUser user = workUsers.stream().filter(f -> Objects.equals(f.getId(), order.getId())).findFirst().orElse(null);
            if (null != user) {
                vo.setUserName(user.getName());
                vo.setUserPhone(user.getPhone());
            }
            vo.setEmp(accounts.stream().filter(f -> Objects.equals(f.getId(), order.getEmpId())).map(ZjAccount::getName).findFirst().orElse(""));
            return vo;
        }).toList();
        return PageUtil.pageList(pageUtil.getPage(), pageUtil.getLimit(), workOrderService.getNetworkDetailOrderListCount(networkId), voList);
    }

    // 获取服务商详情之工单配件列表
    @Override
    public Map<String, Object> getNetworkDetailOrderSpareList(Long networkId, PageUtil pageUtil) {
        return conWorkSpareService.getNetworkDetailOrderSpareList(networkId, pageUtil);
    }

    // 获取服务商详情之工单费用列表
    @Override
    public Map<String, Object> getNetworkDetailOrderFeeList(Long networkId, PageUtil pageUtil) {
        return workFeeService.getNetworkDetailOrderFeeList(networkId, pageUtil);
    }

    // 获取服务商详情之服务商结算
    @Override
    public Map<String, Object> getNetworkDetailModuleSettlementList(Long networkId, PageUtil pageUtil) {
        PageUtil.setPageLimit(pageUtil);
        QueryWrapper<ZjNetworkModuleSettlement> moduleSettlementQueryWrapper = new QueryWrapper<>();
        moduleSettlementQueryWrapper.select("id", "module_id", "price", "gmt_create", "gmt_update")
                .eq("network_id", networkId);
        Page<ZjNetworkModuleSettlement> page = networkModuleSettlementService.page(new Page<>(pageUtil.getPage(), pageUtil.getLimit()), moduleSettlementQueryWrapper);
        List<ZjWorkModule> moduleList = workModuleService.getPartInfoByIds(page.getRecords().stream().map(ZjNetworkModuleSettlement::getModuleId).toList());
        return PageUtil.pageList(page.getCurrent(), page.getSize(), page.getTotal(), page.getRecords().stream().map(settlement -> {
            NetworkModuleSettlementListVo vo = new NetworkModuleSettlementListVo();
            BeanUtil.copyProperties(settlement, vo);
            moduleList.stream().filter(f -> Objects.equals(f.getId(), settlement.getModuleId())).findFirst().ifPresent(module -> {
                vo.setModuleName("【" + WorkConverter.moduleTypeConverter(module.getType()) + "】" + module.getName());
            });
            vo.setCreateTime(settlement.getGmtCreate());
            vo.setUpdateTime(settlement.getGmtUpdate());
            return vo;
        }).toList());
    }

    // 获取服务商详情之资质认证信息
    @Override
    public List<FieldValVo> getNetworkDetailAuthenField(Long networkId) {
        ZjNetwork network = networkService.getById(networkId);
        Assert.notNull(network, "服务商参数[ "+ networkId +" ]的数据不存在");
        if (network.getTeamType() == 1) {
            return networkTeamAuthenFieldValService.getByNetworkId(networkId);
        }
        return networkAloneAuthenFieldValService.getByNetworkId(networkId);
    }

    // 批量删除服务商
    @Override
    @Transactional
    public void deleteBatchById(List<Long> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            return;
        }
        List<Long> networkIds = workOrderService.getRelationNetworkIdByNetworkId(ids);
        if (CollectionUtils.isNotEmpty(networkIds)) {
            networkExceptionMessage(networkIds, "服务工单");
        }
        // 工单费用
        networkIds = workFeeService.getRelationByNetworkIds(ids);
        if (CollectionUtil.isNotEmpty(networkIds)) {
            networkExceptionMessage(networkIds, "工单服务费用项目");
        }
        // 工单备件
        networkIds = workSpareService.getRelationByNetworkIds(ids);
        if (CollectionUtil.isNotEmpty(networkIds)) {
            networkExceptionMessage(networkIds, "工单备件");
        }
        // TODO 出入库
        networkModuleSettlementService.deleteBatchByNetworkIds(ids);
        networkServiceAreaService.deleteBatchByIds(ids);
        networkFieldValService.deleteBatchByNetworkIds(ids);
        networkPathService.removeByIds(ids);
        networkEmpRelationService.deleteBatchByNetworkIds(ids);
        networkStrategyService.removeByIds(ids);
        networkService.removeByIds(ids);
    }

    // 批量更改团队模式
    @Override
    public void updateNetworkTeamType(Long custAccId, List<Long> ids, Integer teamType) {
        if (CollectionUtils.isEmpty(ids)) {
            return;
        }
        if (teamType == NetworkConstant.NETWORK_TEAM_TYPE_2) {
            QueryWrapper<ZjNetwork> networkQueryWrapper = new QueryWrapper<>();
            networkQueryWrapper.select("id", "name", "team_type")
                    .eq("team_type", NetworkConstant.NETWORK_TEAM_TYPE_1)
                    .eq("cust_acc_id", custAccId)
                    .in("id", ids);
            List<ZjNetwork> networkList = networkService.list(networkQueryWrapper);
            if (CollectionUtil.isNotEmpty(networkList)) {
                QueryWrapper<ZjNetworkEmpRelation> empRelationQueryWrapper = new QueryWrapper<>();
                empRelationQueryWrapper.select("network_id")
                        .in("network_id", networkList.stream().map(ZjNetwork::getId).toList());
                List<ZjNetworkEmpRelation> empRelationList = networkEmpRelationService.list(empRelationQueryWrapper);
                List<String> network = networkList.stream().filter(f -> empRelationList.stream().filter(f2 -> Objects.equals(f2.getNetworkId(), f.getId())).count() > 1).map(ZjNetwork::getName).toList();
                Assert.isTrue(CollectionUtil.isEmpty(network), "当前服务商为团队模式，且人员存在两个或以上人数，无法更改团队类型的服务商：" + String.join("、", network));
            }
        }
        List<ZjNetwork> networkList = new ArrayList<>();
        ZjNetwork network = null;
        for (Long id : ids) {
            network = new ZjNetwork();
            network.setId(id);
            network.setTeamType(teamType);
            networkList.add(network);
        }
        networkService.updateBatchById(networkList);
    }


    private void networkExceptionMessage(List<Long> ids, String message) {
        QueryWrapper<ZjNetwork> wrapper = new QueryWrapper<>();
        wrapper.select("name");
        wrapper.in("id", ids);
        String networkNames = networkService.list(wrapper).stream().map(ZjNetwork::getName).collect(Collectors.joining("、"));
        Assert.isTrue(false, "服务商["+ networkNames +"]已与"+ message +"关联使用中，不可删除");
    }
}
